/**
 * @filename:ProcureServiceImpl Mar 5, 2024
 * @project Wonder Vue Admin Api  1.1.0
 * Copyright(c) 2022 Wonder Co. Ltd. 
 * All right reserved. 
 */
package com.wonder.app.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.vtuzx.core.bean.dto.VtuzxMap;
import com.vtuzx.core.utils.VtuzxUtil;
import com.wonder.app.domain.*;
import com.wonder.app.mapper.ProcureDao;
import com.wonder.app.mapper.ProcureDetailDao;
import com.wonder.app.service.InventoryService;
import com.wonder.app.service.ProcureDetailService;
import com.wonder.app.service.ProcureService;
import com.wonder.app.request.ProcureRequest;
import com.wonder.bean.kingdee.xqc.BillMaterial;
import com.wonder.common.utils.DateUtils;
import com.wonder.common.utils.StringUtils;
import com.wonder.common.utils.MessageUtils;
import com.wonder.common.common.AjaxResult;

import java.util.*;

import com.wonder.constant.BillEvent;
import com.wonder.constant.BillType;
import com.wonder.constant.IXqcConst;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

/**   
 * @Description:TODO(采购入库服务实现)
 *
 * @version: 1.1.0
 * @author: Wonder
 * 
 */
@Service
public class ProcureServiceImpl  extends ServiceImpl<ProcureDao, Procure> implements ProcureService  {
	private static final Logger _logger = LoggerFactory.getLogger(ProcureDetailServiceImpl.class);

	@Autowired
	private ProcureDao procureDao;

	@Autowired
	private ProcureDetailDao procureDetailDao;

	@Autowired
	private InventoryService inventoryService;

	@Autowired
	private ProcureService procureService;

	@Autowired
	private ProcureDetailService procureDetailService;
    /**
     * 验证采购入库信息
     * 
     * @param procure
     * @param type
     * @return String
     */
    @Override
    public String validate(Procure procure,String type){
    
    
       return "";
    }
    
    
    /**
	 * Description:采购入库分页返回
	 * @param request //检索条件
	 * @param page //分页参数
	 * @return IPage<Procure>   //分页记录
	 */
	@Override 
	public IPage<Procure> selectList(ProcureRequest request, Page<Procure> page){
	    LambdaQueryWrapper<Procure> lambdaQueryWrapper = new LambdaQueryWrapper<>();
	    
	    if (null != request.getBillNo()) {
	       lambdaQueryWrapper.like(Procure::getBillNo, request.getBillNo());
	      }
		if (null != request.getCreateTime()){
			Date[] createTime = request.getCreateTime();
			if(createTime.length > 0)
				lambdaQueryWrapper.ge(Procure::getCreateTime, createTime[0]);
			if(createTime.length == 2)
				lambdaQueryWrapper.le(Procure::getCreateTime, DateUtils.dateToStr(createTime[1],"yyyy-MM-dd") + " 23:59:59");
		}
        
		lambdaQueryWrapper.orderByDesc(Procure::getId);	
		Page<Procure> selectPage = this.baseMapper.selectPage(page, lambdaQueryWrapper);
		return selectPage;
    }

	@Override
	public VtuzxMap getDetail(String billNo) {
		VtuzxMap data = new VtuzxMap();
		List<ProcureDetail> detailList = procureDetailDao.selectList(new QueryWrapper<ProcureDetail>()
				.eq("billNo", billNo));

		Procure procure = procureDao.selectOne(new LambdaQueryWrapper<Procure>().
				eq(Procure::getBillNo,billNo));
		data.append("header",procure)
				.append("dataList",detailList);
		return data;
	}

	@Override
	public boolean unAuditProcure(Long user_id, String userName, Long id) {
		Procure procure = procureDao.selectById(id);
		procure.setUpdateUserName(userName);
		procure.setStatus("unAudit");
		String billNo = procure.getBillNo();

		//反审需要把已经入库的库存减少
		List<ProcureDetail> detailList = procureDetailDao.selectList(new QueryWrapper<ProcureDetail>()
				.eq("entryId", id));

		List<BillMaterial> dataList = new ArrayList<>();//需要增加的库存
		for (ProcureDetail data : detailList) {
			BillMaterial material = new BillMaterial();
			material.setMaterialNo(data.getMaterialNo());
			material.setMaterialName(data.getMaterialName());
			material.setMaterialModel(data.getSpecification());
			material.setCount(data.getCount());
			material.setStockNo(data.getStockNo());
			material.setBatchNo(data.getFlot());
			material.setUnit(data.getUnit());
			material.setProduceDate(data.getProduceDate());
			material.setExpiryDate(data.getExpiryDate());
			material.setProduce(data.getIsProduce());
			material.setFlot(data.getIsFlot());
			dataList.add(material);
		}
		try {
			Map<String, Object> stringObjectMap = inventoryService.reduceInventory(user_id, userName, BillEvent.Unaudit, BillType.CGRK, billNo, dataList);
			if (!(Boolean) stringObjectMap.get("status")){
				return false;
			}
		} catch (Exception e){
			_logger.info(e.getMessage());
		}

		boolean isSuccess = procureService.updateById(procure);

		return isSuccess;
	}

	@Override
	public boolean auditProcure(Long user_id, String userName, String billNo) {
		Procure procure = procureDao.selectOne(new LambdaQueryWrapper<Procure>().eq(Procure::getBillNo,billNo));
//		procure.setUpdateTime(new DateTime());
		procure.setUpdateUserName(userName);
		procure.setStatus("audit");
		procure.setAuditTime(new DateTime());
		procure.setAuditUserName(userName);

		//审核订单需要扣减库存
		List<ProcureDetail> detailList = procureDetailDao.selectList(new QueryWrapper<ProcureDetail>()
				.eq("billNo", billNo));

		List<BillMaterial> dataList = new ArrayList<>();//需要扣减的库存
		for (ProcureDetail data : detailList) {
			BillMaterial material = new BillMaterial();
			material.setMaterialNo(data.getMaterialNo());
			material.setMaterialName(data.getMaterialName());
			material.setMaterialModel(data.getSpecification());
			material.setCount(data.getCount());
			material.setStockNo(data.getStockNo());
			material.setBatchNo(data.getFlot());
			material.setUnit(data.getUnit());
			material.setProduceDate(data.getProduceDate());
			material.setExpiryDate(data.getExpiryDate());
			material.setProduce(data.getIsProduce());
			material.setFlot(data.getIsFlot());
			dataList.add(material);
		}
		try {
			Map<String, Object> stringObjectMap = inventoryService.addInventory(user_id, userName, BillEvent.Audit, BillType.QTRK, billNo, dataList);

			if (!(Boolean) stringObjectMap.get("status")){
				return false;
			}

		} catch (Exception e){
			_logger.info(e.getMessage());

		}

		boolean isSuccess = procureService.updateById(procure);

		return isSuccess;
	}

	@Override
	public boolean saveProcure(String userName, Map<String, Object> header, List<Map<String, Object>> dataList) {
		List<ProcureDetail> detailList = new ArrayList<>();
		double sumCount = 0;
		for (Map<String,Object> map : dataList) {
			ProcureDetail detail = new ProcureDetail();
			detail.setId(VtuzxUtil.getLong(map,"id"));
			detail.setBillNo(VtuzxUtil.getString(map,"billNo"));
			detail.setMaterialNo(VtuzxUtil.getString(map,"materialNo"));
			detail.setMaterialName(VtuzxUtil.getString(map,"materialName"));
			detail.setSpecification(VtuzxUtil.getString(map,"specification"));
			detail.setFlot(VtuzxUtil.getString(map,"flot"));
			detail.setProduceDate(VtuzxUtil.parseDate(VtuzxUtil.getString(map,"produceDate")));
			detail.setExpiryDate(VtuzxUtil.parseDate(VtuzxUtil.getString(map,"expiryDate")));
			detail.setUnit(VtuzxUtil.getString(map,"unit"));
			detail.setStockNo(VtuzxUtil.getString(map,"stockNo"));
			detail.setCount(VtuzxUtil.getDouble(map,"count"));
			detail.setIsProduce(VtuzxUtil.getBoolean(map,"isProduce"));
			detail.setIsFlot(VtuzxUtil.getBoolean(map,"isFlot"));
			detail.setUpdateUserName(userName);
			detail.setUpdateTime(new DateTime());
			detailList.add(detail);
			sumCount += VtuzxUtil.getDouble(map,"count");
		}
		//修改外层的数量
		Long id = Long.parseLong(header.get("id").toString());
		Procure procure = procureDao.selectById(id);
		procure.setCount(sumCount);
		procure.setStatus("save");
		boolean pickRes = procureService.updateById(procure);
		boolean res = procureDetailService.saveOrUpdateBatch(detailList);
		return res && pickRes;
	}

	@Override
	public boolean saveProcurePad(JSONObject map) {
		String userName = map.getStr("userName");
		String remark = map.getStr("remark");
		Long userId = map.getLong("userId");
		JSONArray jsonArray = map.getJSONArray("material");//物料信息
		List<ProcureDetail> detailList = new ArrayList<>();
		String billNo = IXqcConst.createBillNo(BillType.CGRK);
		double sumCount = 0;
		String stockNo = "";
		for (int i = 0;i < jsonArray.size(); i++ ) {
			JSONObject jsonObject = jsonArray.getJSONObject(i);
			String materialNo = jsonObject.getStr("materialNo");
			String materialName = jsonObject.getStr("materialName");
			String specification = jsonObject.getStr("specification");
			String batchNo = jsonObject.getStr("batchNo");
			String unit = jsonObject.getStr("unit");
			double count = jsonObject.getDouble("count");
			String produceDate = jsonObject.getStr("produceDate");
			String expiryDate = jsonObject.getStr("expiryDate");
			stockNo = jsonObject.getStr("stockNo");

			ProcureDetail detail = new ProcureDetail();
			//判断有没有启用批次和保质期
			if (!VtuzxUtil.isEmpty(batchNo)){
				detail.setIsFlot(true);
				detail.setFlot(batchNo);
			} else {
				detail.setIsFlot(false);
			}
			if (!VtuzxUtil.isEmpty(produceDate)){
				detail.setIsProduce(true);
				detail.setProduceDate(VtuzxUtil.parseDate(produceDate));
				detail.setExpiryDate(VtuzxUtil.parseDate(expiryDate));
			} else {
				detail.setIsProduce(false);
			}
			detail.setBillNo(billNo);
			detail.setMaterialNo(materialNo);
			detail.setMaterialName(materialName);
			detail.setSpecification(specification);
			detail.setUnit(unit);
			detail.setStockNo(stockNo);
			detail.setCreateUserName(userName);
			detail.setCreateUserId(userId);
			detail.setCount(count);
			detail.setUpdateUserName(userName);

			sumCount += count;

			detailList.add(detail);
		}
		Procure procure = new Procure();
		procure.setBillNo(billNo);
		procure.setCount(sumCount);
		procure.setCreateUserName(userName);
		procure.setCreateUserId(userId);
		procure.setRemark(remark);
		procure.setStockNo(stockNo);
		procureDao.insert(procure);
		procureDetailService.saveBatch(detailList);
		//审核采购入库单
		boolean res = auditProcure(userId, userName, billNo);
		return res;
	}


}